/*
Author: Surpass-HC
Source: https://gitee.com/hxchuan000/clpc-1
Mail: surpass-hc@qq.com
*/
#include <optargs.h>

static void optSetArgVal(argParseStc *argptr, char *argval)
{
    switch (argptr->valtype)
    {
    case ARG_TYPE_C:
    {
        if(argval == NULL)
        {
            argptr->valptr.val_c[0] = 0x80;
            break;
        }
        argptr->valptr.val_c[0] = strtol(argval, NULL, 10);
        break;
    }
    case ARG_TYPE_SH:
    {
        if(argval == NULL)
        {
            argptr->valptr.val_s[0] = 0x8000;
            break;
        }
        argptr->valptr.val_s[0] = strtol(argval, NULL, 10);
        break;
    }
    case ARG_TYPE_I:
    {
        if(argval == NULL)
        {
            argptr->valptr.val_i[0] = 0x80000000;
            break;
        }
        argptr->valptr.val_i[0] = strtol(argval, NULL, 10);
        break;
    }
    case ARG_TYPE_LL:
    {
        if(argval == NULL)
        {
            argptr->valptr.val_ll[0] = 0x8000000000000000LL;
            break;
        }
        argptr->valptr.val_ll[0] = strtoll(argval, NULL, 10);
        break;
    }
    case ARG_TYPE_F:
    {
        if(argval == NULL)
        {
            argptr->valptr.val_f[0] = 0x80000000;
            break;
        }
        argptr->valptr.val_f[0] = strtof(argval, NULL);
        break;
    }
    case ARG_TYPE_D:
    {
        if(argval == NULL)
        {
            argptr->valptr.val_d[0] = 0x80000000;
            break;
        }
        argptr->valptr.val_d[0] = strtod(argval, NULL);
        break;
    }
    case ARG_TYPE_STR:
    {
        if(argval == NULL)
        {
            argptr->valptr.val_str[0] = 0;
            break;
        }
        strncpy(argptr->valptr.val_str, argval, argptr->valsize);
        break;
    }
    default:
    {
        printf("err: arg type err\n");
        break;
    }
    }
}

// a选项 ：因为没有跟冒号，不能有参数，如：-a
// b选项 ：因为后面跟了1个冒号，必须有参数，如：-b 100
// c选项 ：因为跟了2个冒号，参数可有可无，如：-c 100 或 -c 都行
int parseArgCom(int argc, char **argv, argBuffStc *getArgBuf)
{
    char tmpShortOpt[256] = {0};
    struct option *tmpLongOpt;
    int tmpopt;
    if (!getArgBuf)
    {
        printf("rtcptr null\n");
        return -1;
    }
    tmpLongOpt = (struct option *)malloc(sizeof(struct option) * getArgBuf->argsize);
    if(!tmpLongOpt)
    {
        printf("tmpLongOpt malloc null\n");
        return -1;
    }
    int tmpShortCount = 0;
    printf("getArgBuf->argsize=%d\n", getArgBuf->argsize);
    int i;
    for (i = 0; i < getArgBuf->argsize; i++)
    {
        if (tmpShortCount < (int)sizeof(tmpShortOpt))
        {
            tmpShortOpt[tmpShortCount++] = getArgBuf->argbuf[i].names;
        }
        else
        {
            printf("err: short buff full val!\n");
        }
        if (getArgBuf->argbuf[i].has_arg == no_argument)
        {
            ;
        }
        else if ((getArgBuf->argbuf[i].has_arg == required_argument) && tmpShortCount < (int)sizeof(tmpShortOpt))
        {
            tmpShortOpt[tmpShortCount++] = ':';
        }
        else if ((getArgBuf->argbuf[i].has_arg == optional_argument) && tmpShortCount < (int)sizeof(tmpShortOpt) - 1)
        {
            tmpShortOpt[tmpShortCount++] = ':';
            tmpShortOpt[tmpShortCount++] = ':';
        }
        else
        {
            printf("err: short buff full:! [%s]%d\n", getArgBuf->argbuf[i].namel, getArgBuf->argbuf[i].has_arg);
        }
        tmpLongOpt[i].name = getArgBuf->argbuf[i].namel;
        tmpLongOpt[i].has_arg = getArgBuf->argbuf[i].has_arg;
        tmpLongOpt[i].flag = NULL;
        tmpLongOpt[i].val = getArgBuf->argbuf[i].names;
        // printf("%s,%d,%c\n", tmpLongOpt[i].name, tmpLongOpt[i].has_arg, tmpLongOpt[i].val);

    }
    printf("tmpShortOpt:%s\n", tmpShortOpt);
    while (tmpopt = getopt_long(argc, argv, tmpShortOpt, tmpLongOpt, NULL), tmpopt >= 0)
    {
        int i;
        for (i = 0; i < getArgBuf->argsize; i++)
        {
            if(tmpopt == getArgBuf->argbuf[i].names)
            {
                printf("Input [-%c] parameter is:%s\n", getArgBuf->argbuf[i].names, optarg);
                optSetArgVal(&getArgBuf->argbuf[i], optarg);
            }
        }
    }

    if(tmpLongOpt)
    {
        free(tmpLongOpt);
        tmpLongOpt = NULL;
    }
    return 1;
}

int printOptArgInfo(argBuffStc *getArgBuf)
{
    printf("arg info list:%d\n", getArgBuf->argsize);
    int i;
    for(i = 0; i < getArgBuf->argsize; i++)
    {
        printf("[-%c, --%s]  %s\n", getArgBuf->argbuf[i].names, getArgBuf->argbuf[i].namel, getArgBuf->argbuf[i].explain);
    }
    return 0;
}